unit RclCollections;

interface

uses
  JclContainerIntf, JclArrayLists, JclHashSets;

type
  
  TAbstractCollection = class(TInterfacedObject, IJclCollection)
    function Add(AObject: TObject): Boolean; virtual;
    function AddAll(ACollection: IJclCollection): Boolean; virtual;
    procedure Clear; virtual;
    function Contains(AObject: TObject): Boolean; virtual;
    function ContainsAll(ACollection: IJclCollection): Boolean; virtual;
    function Equals(ACollection: IJclCollection): Boolean; virtual;
    function First: IJclIterator; virtual;
    function IsEmpty: Boolean; virtual;
    function Last: IJclIterator; virtual;
    function Remove(AObject: TObject): Boolean; virtual;
    function RemoveAll(ACollection: IJclCollection): Boolean; virtual;
    function RetainAll(ACollection: IJclCollection): Boolean; virtual;
    function Size: Integer; virtual;
  end;

  TAbstractList = class(TAbstractCollection, IJclList)
    function GetObject(Index: Integer): TObject; virtual;
    function IndexOf(AObject: TObject): Integer; virtual;
    procedure Insert(Index: Integer; AObject: TObject); overload; virtual;
    function InsertAll(Index: Integer; ACollection: IJclCollection): Boolean;
        overload; virtual;
    function LastIndexOf(AObject: TObject): Integer; virtual;
    function Remove(Index: Integer): TObject; overload; virtual;
    procedure SetObject(Index: Integer; AObject: TObject); virtual;
    function SubList(First, Count: Integer): IJclList; virtual;
  end;


  TSingletonList = class(TAbstractList)
  private
    element: TObject;
  public
    constructor Create(obj: TObject);
    function Contains(AObject: TObject): Boolean; override;
    function GetObject(Index: Integer): TObject; override;
    function Size: Integer; override;
  end;

  TEMPTY_LIST = class(TAbstractList)
  public
    function Contains(AObject: TObject): Boolean; override;
    function GetObject(Index: Integer): TObject; override;
    function Size: Integer; override;
  end;  
  
  Collections = class(TObject)
  private
  protected
  public
    class function ToIntfCollection(AIn: IJclCollection): IJclIntfCollection;
    class function EMPTY_LIST: IJclList;
    class function EMPTY_SET: IJclSet;
    class function singletonList(aObject: TObject): IJclCollection; overload;
    class function singletonList(aIntf: IInterface): IJclIntfCollection; overload;
    class function UnmodifiableCollection(aCollection: IJclCollection):
        IJclCollection; overload;
    class function UnmodifiableCollection(aCollection: IJclIntfCollection):
        IJclIntfCollection; overload;
    class function UnmodifiableList(aList: IJclIntfList): IJclIntfList; overload;
    class function UnmodifiableList(aList: IJclList): IJclList; overload;
    class function unmodifiableMap(aSet: IJclStrStrMap): IJclStrStrMap;
    class function unmodifiableSet(aSet: IJclStrSet): IJclStrSet;
  end;

implementation

uses
  SysUtils, Classes;

class function Collections.ToIntfCollection(AIn: IJclCollection):
    IJclIntfCollection;
var
  it: IJclIterator;
  intf: IInterface;
begin
  Result := TJclIntfArrayList.Create;
  it := AIn.First;
  while it.HasNext do
    if Supports(it.Next, IInterface, intf) then
      Result.Add(intf)
end;

class function Collections.EMPTY_LIST: IJclList;
begin
  Result := TEMPTY_LIST.Create;
end;

class function Collections.EMPTY_SET: IJclSet;
begin
  Result := nil;
end;

class function Collections.singletonList(aObject: TObject): IJclCollection;
begin
  Result := TSingletonList.Create(aObject);
end;

class function Collections.singletonList(aIntf: IInterface): IJclIntfCollection;
begin
  Result := TJclIntfArrayList.Create;
  Result.Add(aIntf);
end;

class function Collections.UnmodifiableCollection(aCollection: IJclCollection):
    IJclCollection;
begin
  Result := aCollection;
end;

class function Collections.UnmodifiableCollection(aCollection:
    IJclIntfCollection): IJclIntfCollection;
begin
  Result := aCollection;
end;

class function Collections.UnmodifiableList(aList: IJclIntfList): IJclIntfList;
begin
  Result := aList;
end;

class function Collections.UnmodifiableList(aList: IJclList): IJclList;
begin
  Result := aList;
end;

class function Collections.unmodifiableMap(aSet: IJclStrStrMap): IJclStrStrMap;
begin
  Result := aSet;
  // TODO -cMM: Collections.unmodifiableMap default body inserted
end;

class function Collections.unmodifiableSet(aSet: IJclStrSet): IJclStrSet;
begin
  Result := aSet;
  // TODO -cMM: Collections.unmodifiableSet default body inserted
end;

function TAbstractCollection.Add(AObject: TObject): Boolean;
begin
  //no-
end;

function TAbstractCollection.AddAll(ACollection: IJclCollection): Boolean;
begin
  // TODO -cMM: TAbstractList.AddAll default body inserted
end;

procedure TAbstractCollection.Clear;
begin
  // TODO -cMM: TAbstractList.Clear default body inserted
end;

function TAbstractCollection.Contains(AObject: TObject): Boolean;
begin
  // TODO -cMM: TAbstractList.Contains default body inserted
end;

function TAbstractCollection.ContainsAll(ACollection: IJclCollection): Boolean;
begin
  // TODO -cMM: TAbstractList.ContainsAll default body inserted
end;

function TAbstractCollection.Equals(ACollection: IJclCollection): Boolean;
begin
  // TODO -cMM: TAbstractList.Equals default body inserted
end;

function TAbstractCollection.First: IJclIterator;
begin
  // TODO -cMM: TAbstractList.First default body inserted
end;

function TAbstractCollection.IsEmpty: Boolean;
begin
  // TODO -cMM: TAbstractList.IsEmpty default body inserted
end;

function TAbstractCollection.Last: IJclIterator;
begin
  // TODO -cMM: TAbstractList.Last default body inserted
end;

function TAbstractCollection.Remove(AObject: TObject): Boolean;
begin
  // TODO -cMM: TAbstractList.Remove default body inserted
end;

function TAbstractCollection.RemoveAll(ACollection: IJclCollection): Boolean;
begin
  // TODO -cMM: TAbstractList.RemoveAll default body inserted
end;

function TAbstractCollection.RetainAll(ACollection: IJclCollection): Boolean;
begin
  // TODO -cMM: TAbstractList.RetainAll default body inserted
end;

function TAbstractCollection.Size: Integer;
begin
  // TODO -cMM: TAbstractList.Size default body inserted
end;

function TEMPTY_LIST.Contains(AObject: TObject): Boolean;
begin
  Result := False;
end;

function TEMPTY_LIST.GetObject(Index: Integer): TObject;
begin
  raise Exception.Create(Format('Index out of bounds.(Index: %s)', [IntToStr(Index)]));
end;

function TEMPTY_LIST.Size: Integer;
begin
  Result := 0;
end;

function TAbstractList.GetObject(Index: Integer): TObject;
begin
  // TODO -cMM: TAbstractList.GetObject default body inserted
end;

function TAbstractList.IndexOf(AObject: TObject): Integer;
begin
  // TODO -cMM: TAbstractList.IndexOf default body inserted
end;

procedure TAbstractList.Insert(Index: Integer; AObject: TObject);
begin
  // TODO -cMM: TAbstractList.Insert default body inserted
end;

function TAbstractList.InsertAll(Index: Integer; ACollection: IJclCollection):
    Boolean;
begin
  // TODO -cMM: TAbstractList.InsertAll default body inserted
end;

function TAbstractList.LastIndexOf(AObject: TObject): Integer;
begin
  // TODO -cMM: TAbstractList.LastIndexOf default body inserted
end;

function TAbstractList.Remove(Index: Integer): TObject;
begin
  // TODO -cMM: TAbstractList.Remove default body inserted
end;

procedure TAbstractList.SetObject(Index: Integer; AObject: TObject);
begin
  // TODO -cMM: TAbstractList.SetObject default body inserted
end;

function TAbstractList.SubList(First, Count: Integer): IJclList;
begin
  // TODO -cMM: TAbstractList.SubList default body inserted
end;

constructor TSingletonList.Create(obj: TObject);
begin
  element := obj
end;

function TSingletonList.Contains(AObject: TObject): Boolean;
begin
  Result := (AObject = element);
end;

function TSingletonList.GetObject(Index: Integer): TObject;
begin
  if (index <> 0) then
      raise Exception.Create(Format('Index out of bounds.(Index: %s, Size: 1)', [IntToStr(Index)]));
  Result := element;
end;

function TSingletonList.Size: Integer;
begin
  Result := 1;
end;

end.
